package com.xuzmian.demo.kotlin

interface BaseInterFace {
    // 接口成员默认就是“open”的
    fun foo(){println("BaseInterFace method foo run ") }
}

/**
 * 声明一个抽象类：由于抽象类必须可以被继承，所以无需再加open关键字
 */
abstract class BaseClass(p: Int) {
    //主构造函数的初始化代码块
    init {
        println("BaseClass main constructor p=$p")
    }

    /**
     * 次构造函数：如果类有一个主构造函数，每个次构造函数需要委托给主构造函数， 可以直接委托或者通过别的次构造函数间接委托
     */
    constructor(p: Int, f: Float) : this(p) {
        println("BaseClass minor constructor p=$p,f=$f")
    }

    abstract fun abstractFun(): BaseClass

    /**
     * 可以被覆盖的成员
     */
    open fun foo() {
        println("it's BaseClass foo method")
    }
}


class DerivedClass(p: Int, des: String) : BaseClass(p), BaseInterFace {
    /**
     * 主构造的参数可以在初始化块中使用，它们也可以在类体内声明的属性初始化器中使用。
     */
    var desUpperCase = des.toUpperCase()

    /**
     * 初始化块中的代码实际上会成为主构造函数的一部分,委托给主构造函数会作为次构造函数的第一条语句，因此所有初始化块中的代码都会在次构造函数体之前执行。
     */
    init {
        println("BaseClass main constructor desUpperCase=$desUpperCase")
    }

    /**
     * 实现父类方法
     */
    override fun abstractFun(): BaseClass {
        println("it's DerivedClass abstractFun method")
        return this
    }

    /**
     * 覆盖父类开放方法
     * 注意：如果一个类从它的直接超类继承相同成员的多个实现， 它必须覆盖这个成员并提供其自己的实现
     */
    override fun foo() {
        super<BaseInterFace>.foo()
        super<BaseClass>.foo()
        println("it's DerivedClass foo method")
    }
}

